# !/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time    : 2019/8/19 14:15
# @Author  : LiHaowen
# @Email   : lihaowen2017@163.com
from __future__ import unicode_literals
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.conf import settings
from slugify import slugify
from taggit.managers import TaggableManager
from markdownx.models import MarkdownxField
from markdownx.utils import markdownify


@python_2_unicode_compatible
class ArticleQuerySet(models.query.QuerySet):
    """自定义QuerySet，提高模型类的可用性增加queryset api，对象.object.自定义方法"""
    def get_published(self):
        """获取已发表的文章"""
        return self.filter(status="P").select_related('user')

    def get_drafts(self):
        """获取草稿箱的文章"""
        return self.filter(status="D").select_related('user')

    def get_counted_tags(self):
        """统计所有已发表的文章中，每一个标签的数量(大于0的)"""
        tag_dict = {}
        # annotate(tagged=models.Count('tags')) 根据tags字段聚合分组
        query = self.get_published().annotate(tagged=models.Count('tags')).filter(tags__gt=0)
        for obj in query:
            for tag in obj.tags.names():
                if tag not in tag_dict:
                    tag_dict[tag] = 1
                else:
                    tag_dict[tag] += 1
        return tag_dict.items()


@ python_2_unicode_compatible
class Article(models.Model):

    STATUS = (("D", "Draft"), ("P", "Published"))
    # 草稿，发布

    title = models.CharField(max_length=255, unique=True, verbose_name="标题")
    # 因为用户可能因为某些原因被注销，所以user可以设置为空
    user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True,
                             on_delete=models.SET_NULL, related_name="author")
    image = models.ImageField(upload_to="articles_pictures/%Y/%m/%d/", verbose_name="文章图片")
    slug = models.SlugField(max_length=255, verbose_name="(URL)别名")
    status = models.CharField(max_length=1, choices=STATUS, default="D", verbose_name="状态")
    content = MarkdownxField(verbose_name="内容")
    edited = models.BooleanField(default=False, verbose_name="是否可编辑")
    # tags字段当做多对多标签使用，将taggit添加至应用
    tags = TaggableManager(help_text="多个标签使用,(英文)隔开", verbose_name="标签")
    created_at = models.DateTimeField(db_index=True, auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    objects = ArticleQuerySet.as_manager()  # 类似于重写object方法

    class Meta:
        verbose_name = "文章"
        verbose_name_plural = verbose_name
        db_table = "tb_article"
        ordering = ("created_at", )

    def __str__(self):
        return self.title

    def save(self, force_insert=False, force_update=False, using=None,
             update_fields=None):
        """重写save方法将标签名利用slugify进行别名存储到slug中"""
        self.slug = slugify(self.title)
        super(Article, self).save()

    def get_markdown(self):
        """将markdown文本转换成HTML"""
        return markdownify(self.content)

